package com.dcits.account.config;

import com.dcits.account.common.LoginFailedException;
import com.dcits.account.entity.cto.OutputObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Auther: 2843896844@qq.com
 * @Date: 2020/12/04/16:05
 * @Description:
 */
@ControllerAdvice
public class ExceptionResolver {

    private Logger log = LoggerFactory.getLogger(ExceptionResolver.class);

    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView LoginFailedExceptionResolver(
            LoginFailedException exception,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
        log.error(exception.getMessage());
        String viewName = "login";
        return commonResolveException(exception, request, response, viewName);
    }

    /**
     * 核心异常处理方法
     *
     * @param exception SpringMVC捕获到的异常对象
     * @param request   为了判断当前请求是“普通请求”还是“Ajax请求”需要传入原生request对象
     * @param response  为了能够将JSON字符串作为当前请求的响应数据返回给浏览器
     * @param viewName  指定要前往的视图名称
     * @return ModelAndView
     * @throws IOException
     */
    private ModelAndView commonResolveException(
            Exception exception,
            HttpServletRequest request,
            HttpServletResponse response,
            String viewName
    ) throws IOException {
        boolean judgeResult = this.udgeRequestType(request);
        if (judgeResult) {
            String message = exception.getMessage();
            OutputObject outputObject = new OutputObject();
            outputObject.setRtnCode(OutputObject.FAILED_CODE);
            outputObject.setRtnMsg(message);
            String json = outputObject.toJSONString();
            PrintWriter writer = response.getWriter();
            writer.write(json);
            return null;
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", exception.getMessage());
        modelAndView.setViewName(viewName);
        return modelAndView;
    }

    /**
     * 判断当前请求是否为Ajax请求
     */
    private static boolean udgeRequestType(HttpServletRequest request) {
        String acceptInformation = request.getHeader("Accept");
        String xRequestInformation = request.getHeader("X-Requested-With");
        return
                (acceptInformation != null && acceptInformation.length() > 0 && acceptInformation.contains("application/json"))
                        || (xRequestInformation != null && xRequestInformation.length() > 0 && xRequestInformation.equals("XMLHttpRequest"));
    }
}
